import { MergeObjectUtils } from '@/utils/MergeObjectUtils.ts';

/**
 * 数组工具类
 *
 * （1）删除元素：
 * const list = [
 *     { id: 1, name: 'Alice', age: 24 },
 *     { id: 2, name: 'Bob', age: 30 },
 *     { id: 3, name: 'Charlie', age: 28 },
 * ];
 *
 * ArrayUtils.remove(list, 'id', 2); // 删除 id 为 2 的元素
 * console.log(list); // [{ id: 1, name: 'Alice', age: 24 }, { id: 3, name: 'Charlie', age: 28 }]
 *
 * （2）更新元素：
 * const list = [
 *     { id: 1, name: 'Alice', age: 24 },
 *     { id: 2, name: 'Bob', age: 30 },
 *     { id: 3, name: 'Charlie', age: 28 },
 * ];
 *
 * // 更新 id 为 2 的元素
 * ArrayUtils.update(list, 'id', 2, { id: 2, name: 'Bob Updated', age: 31 });
 * // [{ id: 1, name: 'Alice', age: 24 }, { id: 2, name: 'Bob Updated', age: 31 }, { id: 3, name: 'Charlie', age: 28 }]
 * console.log(list);
 *
 * （3）查找元素：
 * const list = [
 *     { id: 1, name: 'Alice', age: 24 },
 *     { id: 2, name: 'Bob', age: 30 },
 *     { id: 3, name: 'Charlie', age: 28 },
 * ];
 *
 * const item = ArrayUtils.find(list, 'id', 2); // 查找 id 为 2 的元素
 * console.log(item); // { id: 2, name: 'Bob', age: 30 }
 *
 * （4）查找元素索引：
 * const list = [
 *     { id: 1, name: 'Alice', age: 24 },
 *     { id: 2, name: 'Bob', age: 30 },
 *     { id: 3, name: 'Charlie', age: 28 },
 * ];
 *
 * const index = ArrayUtils.findIndex(list, 'id', 2); // 查找 id 为 2 的元素的索引
 * console.log(index); // 1
 */
export default class ArrayUtils {

    /**
     * 添加元素到数组（触发响应式更新）
     *
     * @param array 目标数组
     * @param item  要添加的元素
     */
    static add<T>(array: T[], item: T): void {
        if (!array || !item) {
            console.warn('Array or item is null or undefined');
            return;
        }

        array.splice(array.length, 0, item);
    }

    /**
     * 删除数组中的元素（触发响应式更新）
     *
     * @param array       目标数组
     * @param rowKey      唯一标识字段
     * @param rowKeyValue 唯一标识字段的值
     */
    static remove<T>(array: T[], rowKey: keyof T, rowKeyValue: T[keyof T]): void {
        if (!array || !rowKey) {
            console.warn('Array or rowKey is null or undefined');
            return;
        }

        const index = array.findIndex(item => item[rowKey] === rowKeyValue);
        if (index !== -1) {
            array.splice(index, 1);
        }
    }

    /**
     * 更新数组中的元素（触发响应式更新）
     *
     * @param array       目标数组
     * @param rowKey      唯一标识字段
     * @param rowKeyValue 唯一标识字段的值
     * @param newItem 新的元素
     */
    static update<T>(array: T[], rowKey: keyof T, rowKeyValue: T[keyof T], newItem: T): void {
        try {
            if (!array || !rowKey || !newItem) {
                console.warn('Array, rowKey, or newItem is null or undefined');
                return;
            }

            const index = array.findIndex(item => item[rowKey] === rowKeyValue);
            if (index !== -1) {
                MergeObjectUtils.shallowMerge(array[index] as Record<string, any>, newItem as Record<string, any>);
            }
        } catch (e) {
            console.log('Error updating item:', e);
        }
    }

    /**
     * 查找数组中的元素
     *
     * @param array       目标数组
     * @param rowKey      唯一标识字段
     * @param rowKeyValue 唯一标识字段的值
     * @returns 找到的元素，如果未找到则返回 undefined
     */
    static find<T>(array: T[], rowKey: keyof T, rowKeyValue: T[keyof T]): T | undefined {
        if (!array || !rowKey) {
            console.warn('Array or rowKey is null or undefined');
            return undefined;
        }

        return array.find(item => item[rowKey] === rowKeyValue);
    }

    /**
     * 查找数组中元素的索引
     *
     * @param array       目标数组
     * @param rowKey      唯一标识字段
     * @param rowKeyValue 唯一标识字段的值
     * @returns 元素的索引，如果未找到则返回 -1
     */
    static findIndex<T>(array: T[], rowKey: keyof T, rowKeyValue: T[keyof T]): number {
        if (!array || !rowKey) {
            console.warn('Array or rowKey is null or undefined');
            return -1;
        }

        return array.findIndex(item => item[rowKey] === rowKeyValue);
    }

    /**
     * 在数组中查找指定属性值匹配的对象
     *
     * @param arr       要搜索的数组
     * @param propName  属性名
     * @param propValue 属性值
     * @returns 找到的对象，未找到返回 null
     */
    static findItemByProperty<T extends Record<string, any>>(arr: T[],
                                                             propName: keyof T,
                                                             propValue: T[keyof T]): T | null {

        const item = arr.find(item => item[propName] === propValue);
        return item ? item : null;
    }

    /**
     * 在数组中查找指定属性值匹配的对象，支持深层属性路径查找
     * @param arr         要搜索的数组
     * @param propPath    属性路径（支持点表示法如 'a.b.c'）
     * @param propValue   要匹配的值
     * @returns 找到的对象，未找到返回 null
     */
    static findItemByPropertyEnhanced<T extends Record<string, any>>(arr: T[],
                                                                     propPath: string,
                                                                     propValue: any): T | null {

        const item = arr.find(item => {
            const value = propPath.split('.').reduce((obj, key) => obj?.[key], item);
            return value === propValue;
        });
        return item ? item : null;
    }
}
